package com.yimu.ymblog.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yimu.ymblog.admin.service.AdminTagService;
import com.yimu.ymblog.common.domain.admin.vo.tag.*;
import com.yimu.ymblog.common.domain.dos.ArticleTagRelDO;
import com.yimu.ymblog.common.domain.dos.TagDO;
import com.yimu.ymblog.common.domain.mapper.ArticleTagRelMapper;
import com.yimu.ymblog.common.domain.mapper.TagMapper;
import com.yimu.ymblog.common.enums.ResponseCodeEnum;
import com.yimu.ymblog.common.exception.BizException;
import com.yimu.ymblog.common.model.vo.SelectRspVO;
import com.yimu.ymblog.common.utils.PageResponse;
import com.yimu.ymblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminTagServiceImpl extends ServiceImpl<TagMapper, TagDO> implements AdminTagService {

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private ArticleTagRelMapper articleTagRelMapper;

    /**
     * 添加标签集合
     *
     * @param addTagReqVO
     * @return
     */
    @Override
    public Response addTag(AddTagReqVO addTagReqVO) {
        // 获取标签名
        List<String> tags = addTagReqVO.getTags();
        // 查询数据库中是否有重复
        tags.forEach((tag) -> {
            TagDO tagDo = tagMapper.selectByName(tag);
            if(ObjectUtil.isNotEmpty(tagDo)) {
                throw new BizException(ResponseCodeEnum.TAG_NAME_IS_EXISTED);
            }
        });
        List<TagDO> tagDOS = tags.stream()
                .map(tagName -> TagDO.builder()
                        .name(tagName.trim())
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build())
                .collect(Collectors.toList());
        // 如果没有重复
        this.saveBatch(tagDOS);
        return Response.success();
    }

    /**
     * 标签分页数据获取
     *
     * @param findTagPageListReqVO
     * @return
     */
    @Override
    public Response findTagList(FindTagPageListReqVO findTagPageListReqVO) {
        Long current = findTagPageListReqVO.getCurrent();
        Long size = findTagPageListReqVO.getSize();
        // 封装分页条件
        Page<TagDO> page = new Page<>(current, size);

        // 封装查询条件
        LambdaQueryWrapper<TagDO> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .like(StrUtil.isNotBlank(findTagPageListReqVO.getName()), TagDO::getName, findTagPageListReqVO.getName())
                .ge(ObjectUtil.isNotEmpty(findTagPageListReqVO.getStartDate()), TagDO::getCreateTime, findTagPageListReqVO.getStartDate())
                .le(ObjectUtil.isNotEmpty(findTagPageListReqVO.getEndDate()), TagDO::getUpdateTime, findTagPageListReqVO.getEndDate())
                .orderByDesc(TagDO::getCreateTime);
        Page<TagDO> tagDoPage = tagMapper.selectPage(page, wrapper);

        List<TagDO> TagDOS = tagDoPage.getRecords();

        List<FindTagPageListRspVO> findTagPageListRspVOS = BeanUtil.copyToList(TagDOS, FindTagPageListRspVO.class);

        return PageResponse.success(tagDoPage, findTagPageListRspVOS);
    }

    /**
     * 删除标签
     *
     * @param deleteTagReqVO
     * @return
     */
    @Override
    public Response deleteTag(DeleteTagReqVO deleteTagReqVO) {
        // 标签 ID
        Long tagId = deleteTagReqVO.getId();

        // 校验该标签下是否有关联的文章，若有，则不允许删除，提示用户需要先删除标签下的文章
        ArticleTagRelDO articleTagRelDO = articleTagRelMapper.selectOneByTagId(tagId);

        if (Objects.nonNull(articleTagRelDO)) {
            log.warn("==> 此标签下包含文章，无法删除，tagId: {}", tagId);
            throw new BizException(ResponseCodeEnum.TAG_CAN_NOT_DELETE);
        }

        // 根据标签 ID 删除
        int count = tagMapper.deleteById(tagId);

        return count == 1 ? Response.success() : Response.fail(ResponseCodeEnum.TAG_NOT_EXISTED);
    }

    /**
     * 根据标签关键词模糊查询
     *
     * @param searchTagsReqVO
     * @return
     */
    @Override
    public Response searchTags(SearchTagsReqVO searchTagsReqVO) {
        String key = searchTagsReqVO.getKey();

        // 执行模糊查询
        List<TagDO> tagDOS = tagMapper.selectByKey(key);

        // do 转 vo
        List<SelectRspVO> vos = null;
        if (!CollectionUtil.isEmpty(tagDOS)) {
            vos = tagDOS.stream()
                    .map(tagDO -> SelectRspVO.builder()
                            .label(tagDO.getName())
                            .value(tagDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }

        return Response.success(vos);
    }

    /**
     * 查询标签 Select 列表数据
     * @return
     */
    @Override
    public Response findTagSelectList() {
        // 查询所有标签, Wrappers.emptyWrapper() 表示查询条件为空
        List<TagDO> tagDOS = tagMapper.selectList(null);

        // DO 转 VO
        List<SelectRspVO> vos = null;
        if (!CollectionUtil.isEmpty(tagDOS)) {
            vos = tagDOS.stream()
                    .map(tagDO -> SelectRspVO.builder()
                            .label(tagDO.getName())
                            .value(tagDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }

        return Response.success(vos);
    }

    /**
     * 编辑回显标签
     *
     * @param showTagReqVO
     * @return
     */
    @Override
    public Response showTag(ShowTagReqVO showTagReqVO) {
        Long id = showTagReqVO.getId();
        // 根据分类id查询分类
        TagDO tagDO = tagMapper.selectById(id);
        return Response.success(tagDO.getName());
    }

    /**
     * 更新标签
     *
     * @param updateTagReqVO
     * @return
     */
    @Override
    public Response updateTag(UpdateTagReqVO updateTagReqVO) {
        String name = updateTagReqVO.getName();
        LambdaUpdateWrapper<TagDO> wrapper = new LambdaUpdateWrapper<TagDO>().eq(TagDO::getName, name);
        if (tagMapper.selectCount(wrapper) > 0) {
            log.warn("==> 标签名称已存在，name: {}", name);
            throw new BizException(ResponseCodeEnum.TAG_IS_EXISTED);
        }
        tagMapper.update(TagDO.builder().name(name).updateTime(LocalDateTime.now()).build(), new LambdaUpdateWrapper<TagDO>().eq(TagDO::getId, updateTagReqVO.getId()));
        return Response.success();
    }

    /**
     * 可视化大屏标签获取
     *
     * @return
     */
    @Override
    public Response findVisTagList() {
        List<TagDO> tagDOS = tagMapper.selectList(null);
        List<FindVisTagListRspVO> findVisTagListRspVOS = tagDOS.stream().map(tagDO -> FindVisTagListRspVO.builder().value(tagDO.getId()).name(tagDO.getName()).build()).collect(Collectors.toList());

        return Response.success(findVisTagListRspVOS);
    }
}